package org.fujene.memoryblock.repli;

import java.io.IOException;

import org.fujene.memoryblock.MemoryBlock;
import org.fujene.structure.Constants;
import org.fujene.structure.InvertIndexData;
import org.fujene.structure.LookupPointer;
import org.fujene.toolbox.ByteConverter;

public class ReplicateInvertIndexBlock extends MemoryBlock{
	private int opt_length = 0;

	public ReplicateInvertIndexBlock(int bodySize, int ID, boolean isAllocate){
		super(bodySize, ID, Constants.MEMORY_TYPE_INVINDEX, isAllocate);
	}

	public InvertIndexData getInvertIndex(int ptr){
		if(ptr > this.bodySize - (PTR + IDDIFF + TERMFREQ)) return null;

		LookupPointer prevPtr = ByteConverter.getPtr(getBody(ptr, PTR));
		if(prevPtr.equals(Constants.EMPTY_PTR)) prevPtr = null;

		ptr += PTR;
		long diffID = ByteConverter.byteToLong(getBody(ptr, IDDIFF));

		ptr += IDDIFF;
		int termfreq = ByteConverter.byteToInt(getBody(ptr, TERMFREQ));

		return new InvertIndexData(prevPtr, diffID, termfreq);
	}

	// 末尾に追加するのみ 相対ポインタ対応
	public LookupPointer setInvertIndex(LookupPointer prevPtr, long diffID, int termfreq){
		int ptr = bodySize - bodyVacancy - (PTR + IDDIFF + TERMFREQ);

		opt_length++;

		if(prevPtr == null){
			prevPtr = Constants.EMPTY_PTR;
		}
		setBody(ByteConverter.setPtr(prevPtr), ptr);
		ptr += PTR;
		setBody(ByteConverter.longToByte(diffID, IDDIFF), ptr);
		ptr += 5;
		setBody(ByteConverter.intToByte(termfreq, TERMFREQ), ptr);
		ptr -= 5 + PTR;

		return new LookupPointer(this.getID(), ptr);
	}

	public int getLeft(){
		int left = this.bodyVacancy / (PTR + IDDIFF + TERMFREQ);
		if(left > 0) this.bodyVacancy -= PTR + IDDIFF + TERMFREQ;
		return left;
	}

	@Override
	public int getOptionSize(){
		return 1;
	}

	@Override
	public byte[] getOptionByteStream(){
		return ByteConverter.intToByte(opt_length, 4);
	}

	@Override
	public void setOption(int option, int value){
		if(option == 0) opt_length = value;
	}

	@Override
	public String getClassName(){
		return new String("ExtendInvertIndexBlock");
	}

	@Override
	public byte[] getData() throws IOException{
		throw new NoSuchMethodError("Unimplemented method");
	}

	@Override
	public void setData(byte[] array) throws IOException{
		throw new NoSuchMethodError("Unimplemented method");
	}
}
